package com.djf.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ThreadLocalRandom;

/**
 * 日志测试控制器
 * 用于测试不同级别的日志输出
 * 
 * @author djf
 * @since 2024-01-20
 */
@Slf4j
@RestController
@RequestMapping("/api/log-test")
public class LogTestController {

    /**
     * 触发 DEBUG 级别日志
     */
    @GetMapping("/debug")
    public Map<String, Object> triggerDebugLog() {
        Map<String, Object> result = new HashMap<>();
        
        log.debug("这是一个DEBUG级别的日志 - 调试信息");
        log.debug("用户请求参数: userId={}, action={}", 1001, "debug-test");
        log.debug("SQL执行详情: SELECT * FROM order_202501 WHERE user_id = 1001");
        
        result.put("success", true);
        result.put("message", "DEBUG日志已输出");
        result.put("level", "DEBUG");
        result.put("description", "调试级别日志，包含详细的程序执行信息");
        
        return result;
    }

    /**
     * 触发 INFO 级别日志
     */
    @GetMapping("/info")
    public Map<String, Object> triggerInfoLog() {
        Map<String, Object> result = new HashMap<>();
        
        log.info("这是一个INFO级别的日志 - 业务信息");
        log.info("用户操作记录: 用户[{}]执行了[{}]操作", 1001, "查看订单");
        log.info("系统状态: 当前活跃连接数={}, 内存使用率={}%", 25, 68);
        log.info("分表路由: 订单数据路由到表 order_202501");
        
        result.put("success", true);
        result.put("message", "INFO日志已输出");
        result.put("level", "INFO");
        result.put("description", "信息级别日志，记录重要的业务操作和系统状态");
        
        return result;
    }

    /**
     * 触发 WARN 级别日志
     */
    @GetMapping("/warn")
    public Map<String, Object> triggerWarnLog() {
        Map<String, Object> result = new HashMap<>();
        
        log.warn("这是一个WARN级别的日志 - 警告信息");
        log.warn("数据库连接池警告: 当前连接数已达到80%，当前连接数={}", 8);
        log.warn("分表警告: 目标表 order_202412 不存在，数据将路由到 order_202501");
        log.warn("性能警告: SQL执行时间超过阈值，执行时间={}ms", 1500);
        log.warn("业务警告: 用户[{}]尝试访问不存在的订单[{}]", 1001, "ORDER_NOT_FOUND");
        
        result.put("success", true);
        result.put("message", "WARN日志已输出");
        result.put("level", "WARN");
        result.put("description", "警告级别日志，表示潜在问题但不影响系统正常运行");
        
        return result;
    }

    /**
     * 触发 ERROR 级别日志
     */
    @GetMapping("/error")
    public Map<String, Object> triggerErrorLog() {
        Map<String, Object> result = new HashMap<>();
        
        log.error("这是一个ERROR级别的日志 - 错误信息");
        log.error("数据库连接失败: 无法连接到数据库服务器 localhost:3306");
        log.error("SQL执行异常: java.sql.SQLException: Table 'order_202412' doesn't exist");
        log.error("分片路由异常: 无法确定数据应该路由到哪个表");
        log.error("业务异常: 订单创建失败，用户ID={}, 错误原因={}", 1001, "余额不足");
        
        // 模拟一个异常但不抛出
        try {
            throw new RuntimeException("模拟的业务异常");
        } catch (Exception e) {
            log.error("捕获到异常", e);
        }
        
        result.put("success", true);
        result.put("message", "ERROR日志已输出");
        result.put("level", "ERROR");
        result.put("description", "错误级别日志，记录系统错误和异常信息");
        
        return result;
    }

    /**
     * 触发 TRACE 级别日志
     */
    @GetMapping("/trace")
    public Map<String, Object> triggerTraceLog() {
        Map<String, Object> result = new HashMap<>();
        
        log.trace("这是一个TRACE级别的日志 - 跟踪信息");
        log.trace("方法调用跟踪: OrderService.createOrder() 开始执行");
        log.trace("参数详情: order={}, createTime={}", "Order{id=1001}", "2025-01-15 10:30:00");
        log.trace("方法调用跟踪: OrderService.createOrder() 执行完成");
        
        result.put("success", true);
        result.put("message", "TRACE日志已输出");
        result.put("level", "TRACE");
        result.put("description", "跟踪级别日志，最详细的日志信息，通常用于问题诊断");
        
        return result;
    }

    /**
     * 批量触发多种级别日志
     */
    @GetMapping("/batch")
    public Map<String, Object> triggerBatchLogs() {
        Map<String, Object> result = new HashMap<>();
        
        log.trace("批量日志测试开始");
        log.debug("批量日志测试 - DEBUG: 开始执行批量操作");
        log.info("批量日志测试 - INFO: 正在处理批量日志输出");
        log.warn("批量日志测试 - WARN: 这是一个警告信息");
        log.error("批量日志测试 - ERROR: 这是一个错误信息");
        
        result.put("success", true);
        result.put("message", "批量日志已输出");
        result.put("levels", new String[]{"TRACE", "DEBUG", "INFO", "WARN", "ERROR"});
        result.put("description", "一次性输出所有级别的日志");
        
        return result;
    }

    /**
     * 模拟业务异常（会触发ERROR日志）
     */
    @GetMapping("/business-error")
    public Map<String, Object> triggerBusinessError() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 模拟业务逻辑异常
            if (ThreadLocalRandom.current().nextBoolean()) {
                throw new IllegalArgumentException("业务参数验证失败：用户ID不能为空");
            } else {
                throw new IllegalStateException("业务状态异常：订单状态不允许此操作");
            }
        } catch (Exception e) {
            log.error("业务异常捕获", e);
            result.put("success", false);
            result.put("message", "业务异常：" + e.getMessage());
            result.put("level", "ERROR");
            result.put("description", "模拟真实的业务异常场景");
        }
        
        return result;
    }

    /**
     * 模拟SQL异常（会触发ERROR日志）
     */
    @GetMapping("/sql-error")
    public Map<String, Object> triggerSqlError() {
        Map<String, Object> result = new HashMap<>();
        
        // 模拟SQL异常
        log.error("SQL执行异常: java.sql.SQLException: Unknown column 'invalid_column' in 'field list'");
        log.error("SQL语句: SELECT invalid_column FROM order_202501 WHERE user_id = 1001");
        log.error("分表路由信息: 目标表=order_202501, 分片键=create_time");
        
        result.put("success", false);
        result.put("message", "SQL执行异常");
        result.put("level", "ERROR");
        result.put("description", "模拟数据库SQL执行异常");
        
        return result;
    }

    /**
     * 模拟连接超时（会触发WARN和ERROR日志）
     */
    @GetMapping("/connection-timeout")
    public Map<String, Object> triggerConnectionTimeout() {
        Map<String, Object> result = new HashMap<>();
        
        log.warn("数据库连接超时警告: 连接获取时间超过30秒");
        log.warn("连接池状态: 活跃连接={}, 空闲连接={}, 等待队列={}", 10, 0, 5);
        log.error("数据库连接超时: java.sql.SQLTimeoutException: Connection timed out");
        log.error("连接信息: url=jdbc:mysql://localhost:3306/sharding_order_db");
        
        result.put("success", false);
        result.put("message", "数据库连接超时");
        result.put("levels", new String[]{"WARN", "ERROR"});
        result.put("description", "模拟数据库连接超时场景");
        
        return result;
    }

    /**
     * 获取日志测试接口帮助信息
     */
    @GetMapping("/help")
    public Map<String, Object> getLogTestHelp() {
        Map<String, Object> result = new HashMap<>();
        result.put("success", true);
        result.put("message", "日志测试接口说明");
        
        Map<String, Object> apis = new HashMap<>();
        apis.put("DEBUG日志", "GET /api/log-test/debug");
        apis.put("INFO日志", "GET /api/log-test/info");
        apis.put("WARN日志", "GET /api/log-test/warn");
        apis.put("ERROR日志", "GET /api/log-test/error");
        apis.put("TRACE日志", "GET /api/log-test/trace");
        apis.put("批量日志", "GET /api/log-test/batch");
        apis.put("业务异常", "GET /api/log-test/business-error");
        apis.put("SQL异常", "GET /api/log-test/sql-error");
        apis.put("连接超时", "GET /api/log-test/connection-timeout");
        apis.put("帮助信息", "GET /api/log-test/help");
        
        result.put("apis", apis);
        
        Map<String, String> logLevels = new HashMap<>();
        logLevels.put("TRACE", "最详细的日志信息，通常用于问题诊断");
        logLevels.put("DEBUG", "调试信息，包含详细的程序执行信息");
        logLevels.put("INFO", "重要的业务操作和系统状态信息");
        logLevels.put("WARN", "警告信息，表示潜在问题但不影响系统正常运行");
        logLevels.put("ERROR", "错误信息，记录系统错误和异常");
        
        result.put("logLevels", logLevels);
        
        Map<String, String> environments = new HashMap<>();
        environments.put("开发环境(dev)", "所有级别日志都会输出到控制台、文件和Loki");
        environments.put("生产环境(prod)", "只有WARN及以上级别日志输出到文件和Loki，无控制台输出");
        
        result.put("environments", environments);
        
        return result;
    }
}